/*jslint bitwise: true, eqeqeq: true, immed: true, newcap: true, nomen: true,
  onevar: true, plusplus: true, regexp: true, strict: true, undef: true,
  white: true, indent: 4 */
"use strict";
(function () {
    var console, init, print, println, runTests, runTest, ajaxTest, setUpTest,
            ajaxlib, tierDownTest, encodeObjectTest, setupTest, loadTest,
            getTest, postTest, jsonTest, document, scriptTest,
            addStartListenerTest, addSuccessListenerTest, addFailListenerTest,
            addCompleteListenerTest, addSerializeListenerTest, serializeTest;

    document = this.document;

    init = function () {
        console = this.document.getElementsByTagName('tbody')[0];
        runTests();
    };

    runTests = function () {
        runTest('ajaxTest <span id="ajaxTest"></span>', ajaxTest);
        runTest('encodeObjectTest', encodeObjectTest);
        runTest('setupTest', setupTest);
        runTest('loadTest <span id="loadTest"></span>', loadTest);
        runTest('getTest <span id="getTest"></span>', getTest);
        runTest('postTest <span id="postTest"></span>', postTest);
        runTest('jsonTest <span id="jsonTest"></span>', jsonTest);
        runTest('scriptTest <span id="scriptTest"></span>', scriptTest);
        runTest('addStartListenerTest <span id="addStartListenerTest"></span>',
                addStartListenerTest);
        runTest('addSuccessListenerTest <span id="addSuccessListenerTest">' +
                '</span>', addSuccessListenerTest);
        runTest('addFailListenerTest <span id="addFailListenerTest"></span>',
                addFailListenerTest);
        runTest('addCompleteListenerTest <span id="addCompleteListenerTest">' +
                '</span>', addCompleteListenerTest);
        runTest('addSerializeListenerTest <span id="' +
                'addSerializeListenerTest"></span>', addSerializeListenerTest);
        runTest('serializeTest', serializeTest);
    };

    serializeTest = function () {
        var data;
        data = ajaxlib.serialize(document.getElementsByTagName('form')[0]);
        if (ajaxlib.encodeObject(data) !== 'simple=1&multi[0]=a&multi[1]=b&' +
                'multi[4]=c&multi[5][0]=value&checked=1&radio=1&firstSelect=' +
                '1&multiselect[0]=1&multiselect[1]=4&text=some%20text') {
            throw new Error('serialization is faulty');
        }
    };

    addSerializeListenerTest = function () {
        try {
            ajaxlib.addSerializeListener({});
        } catch (e) {
            try {
                ajaxlib.addSerializeListener(function () {
                    document.getElementById('addSerializeListenerTest').
                            innerHTML = 'OK';
                });
                ajaxlib.serialize(document.getElementsByTagName('form')[0]);
            } catch (ex) {
                throw new Error("Does not allows functions: " + ex);
            }
            return;
        }
        throw new Error("Allows non-functions");
    };

    addCompleteListenerTest = function () {
        try {
            ajaxlib.addStartListener({});
        } catch (e) {
            try {
                ajaxlib.addCompleteListener(function () {
                    document.getElementById('addCompleteListenerTest').
                            innerHTML = 'OK';
                });
                ajaxlib.ajax({url: 'non.existing.file'});
            } catch (ex) {
                throw new Error("Does not allows functions: " + ex);
            }
            return;
        }
        throw new Error("Allows non-functions");
    };

    addFailListenerTest = function () {
        try {
            ajaxlib.addStartListener({});
        } catch (e) {
            try {
                ajaxlib.addFailListener(function () {
                    document.getElementById('addFailListenerTest').
                            innerHTML = 'OK';
                });
                ajaxlib.ajax({url: 'non.existing.file'});
            } catch (ex) {
                throw new Error("Does not allows functions: " + ex);
            }
            return;
        }
        throw new Error("Allows non-functions");
    };

    addSuccessListenerTest = function () {
        try {
            ajaxlib.addStartListener({});
        } catch (e) {
            try {
                ajaxlib.addSuccessListener(function () {
                    document.getElementById('addSuccessListenerTest').
                            innerHTML = 'OK';
                });
                ajaxlib.ajax({url: 'index.php'});
            } catch (ex) {
                throw new Error("Does not allows functions");
            }
            return;
        }
        throw new Error("Allows non-functions");
    };

    addStartListenerTest = function () {
        try {
            ajaxlib.addStartListener({});
        } catch (e) {
            try {
                ajaxlib.addStartListener(function () {
                    document.getElementById('addStartListenerTest').innerHTML =
                            'OK';
                });
                ajaxlib.ajax({});
            } catch (ex) {
                throw new Error("Does not allows functions");
            }
            return;
        }
        throw new Error("Allows non-functions");
    };

    scriptTest = function () {
        ajaxlib.script('index.php', {test: 'script'}, function () {});
    };

    jsonTest = function () {
        ajaxlib.json('index.php', {test: 'json'}, function (json, stat, xhr) {
            document.getElementById('jsonTest').innerHTML =
                    ajaxlib.encodeObject(json);
        });
    };

    postTest = function () {
        ajaxlib.post('index.php', {a: 111}, function (response, status, xhr) {
            document.getElementById('postTest').innerHTML = response;
        });
    };

    getTest = function () {
        ajaxlib.get('index.php', {a: 154}, function (response, status, xhr) {
            document.getElementById('getTest').innerHTML = response;
        });
    };

    loadTest = function () {
        ajaxlib.load('index.php?a=b', 'c=d',
                document.getElementById('loadTest'), null);
    };

    setupTest = function () {
        var settings = {
            nonExistingSettingsProperty: 'value'
        };
        try {
            ajaxlib.setup(settings);
        } catch (e) {
            settings = {
                method: 'GET',
                url: 'someURL',
                data: 'someDATA',
                headers: [],
                onSuccess: function (a, b, c) {},
                onFail: function (a, b, c) {}
            };
            settings.headers.AcceptSettings = 'sure';
            try {
                ajaxlib.setup(settings);
            } catch (ex) {
                throw new Error("does not accept correct settings: " + ex);
            }
            return;
        }
        throw new Error("allows non existing settings property");
    };

    encodeObjectTest = function () {
        var testObject, encoded;
        testObject = {
            array: ['a', 'b', 'c', [1, 2, 3.5]],
            simpleValue: 'val',
            number: 15,
            object: {
                propertyA: 'abc',
                propertyB: 'def'
            }
        };
        encoded = ajaxlib.encodeObject(testObject);
        if (encoded !== 'array[0]=a&array[1]=b&array[2]=c&' +
                'array[3][0]=1&array[3][1]=2&array[3][2]=3.5&' +
                'simpleValue=val&number=15&object[propertyA]=abc&' +
                'object[propertyB]=def') {
            throw new Error("implementation is faulty");
        }
    };

    ajaxTest = function () {
        ajaxlib.ajax({
            url: "index.php",
            data: {a: 'b'},
            method: 'POST',
            onSuccess: function (response, status, xhr) {
                document.getElementById('ajaxTest').innerHTML = response;
            }
        });
    };

    setUpTest = function () {
        ajaxlib = new this.AJAXlib2();
    };

    tierDownTest = function () {};

    runTest = function (label, test) {
        print(label);
        try {
            setUpTest();
            test();
            println('<span class="passed"></span>');
        } catch (e) {
            println('<span class="failed"></span>' + e);
        }
        tierDownTest();
    };

    println = function (text) {
        var row = this.document.createElement('tr');
        print(text);
        console.appendChild(row);
    };

    print = function (text) {
        var cell, row;
        cell = this.document.createElement('td');
        cell.innerHTML = text;
        row = console.lastChild;
        if (row !== null) {
            row.appendChild(cell);
        } else {
            row = this.document.createElement('tr');
            row.appendChild(cell);
            console.appendChild(row);
        }
    };

    if (this.addEventListener instanceof Function) {
        this.addEventListener('load', init, false);
    } else {
        this.attachEvent('onload', init);
    }
}());
